package co.recloud.ariadne.model.plan;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import co.recloud.ariadne.model.logical.Table;
import co.recloud.ariadne.model.logical.Transaction;
import co.recloud.ariadne.persistor.KeyValuePersistor;
import co.recloud.ariadne.persistor.KeyValuePersistorImpl;

public class Operator implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -331582967863349393L;
	
	public static final int WORKER = 1;
	public static final int COORDINATOR = 2;
	private int workType;
	transient private Operator parent;
	transient private List<Operator> children;
	private Set<Table> baseTables;
	private Map<String, Table> tableAliases;
	private Transaction transaction;

	public Operator(Transaction transaction) {
		this.setTransaction(transaction);
	}

	/**
	 * @return the parent
	 */
	public Operator getParent() {
		return parent;
	}

	/**
	 * @param parent
	 *            the parent to set
	 */
	public void setParent(Operator parent) {
		this.parent = parent;
	}

	/**
	 * @return the children
	 */
	public List<Operator> getChildren() {
		return children;
	}

	/**
	 * @param children
	 *            the children to set
	 */
	public void setChildren(List<Operator> children) {
		this.children = children;
	}

	/**
	 * @param table
	 *            the table to set
	 */
	public void setTable(Table table) {
		this.table = table;
	}

	/**
	 * @return the table
	 */
	public Table getTable() {
		return table;
	}

	private Table table;

	public void execute(String localhost, int port) {

		return;
	}

	/**
	 * @param baseTables
	 *            the baseTables to set
	 */
	public void setBaseTables(Set<Table> baseTables) {
		this.baseTables = baseTables;
	}

	/**
	 * @return the baseTables
	 */
	public Set<Table> getBaseTables() {
		return baseTables;
	}

	/**
	 * @param tableAliases
	 *            the tableAliases to set
	 */
	public void setTableAliases(Map<String, Table> tableAliases) {
		this.tableAliases = tableAliases;
	}

	/**
	 * @return the tableAliases
	 */
	public Map<String, Table> getTableAliases() {
		return tableAliases;
	}

	/**
	 * @param transaction
	 *            the transaction to set
	 */
	public void setTransaction(Transaction transaction) {
		this.transaction = transaction;
	}

	/**
	 * @return the transaction
	 */
	public Transaction getTransaction() {
		return transaction;
	}

	public List<Map<String, Object>> dumpTable() {
		List<Map<String, Object>> result = null;
		KeyValuePersistor kv = new KeyValuePersistorImpl(transaction);
		Set<String> resultKeys = kv.getAllKeys(table);
		if (resultKeys != null) {
			result = new ArrayList<Map<String, Object>>();
			for (String key : resultKeys) {
				Map<String, Object> row = new HashMap<String, Object>();
				row.putAll(kv.getAllColumns(key, table));
				result.add(row);
			}
		}
		if (table.isResultSet()) {
			kv.dropTable(table);
		}
		return result;
	}

	/**
	 * @param workType the workType to set
	 */
	public void setWorkType(int workType) {
		this.workType = workType;
	}

	/**
	 * @return the workType
	 */
	public int getWorkType() {
		return workType;
	}
}
